x86: fix hypercall continuation cancellation in XENMAPSPACE_gmfn_range compat wrapper
authorJan Beulich <jbeulich@suse.com>
Wed, 28 Nov 2012 09:02:26 +0000 (10:02 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 28 Nov 2012 09:02:26 +0000 (10:02 +0100)
When no continuation was established, there must also not be an attempt
to cancel it - hypercall_cancel_continuation(), in the non-HVM, non-
multicall case, adjusts the guest mode return address in a way assuming
that an earlier call hypercall_create_continuation() took place.

Once touching this code, also restructure it slightly to improve
readability and switch to using the more relaxed copy function (copying
from the same guest memory already validated the virtual address
range).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
xen/arch/x86/x86_64/compat/mm.c

index d1eb7856003eb7e2dcadab38dd6c8165272d9213..808e033a3fe5609f79dff1984e8f0708a6b7a678 100644 (file)
@@ -66,21 +66,20 @@ int compat_arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg)
         XLAT_add_to_physmap(nat, &cmp);
         rc = arch_memory_op(op, guest_handle_from_ptr(nat, void));
 
-        if ( cmp.space == XENMAPSPACE_gmfn_range )
+        if ( !rc || cmp.space != XENMAPSPACE_gmfn_range )
+            break;
+
+        XLAT_add_to_physmap(&cmp, nat);
+        if ( __copy_to_guest(arg, &cmp, 1) )
         {
-            if ( rc )
-            {
-                XLAT_add_to_physmap(&cmp, nat);
-                if ( copy_to_guest(arg, &cmp, 1) )
-                {
-                    hypercall_cancel_continuation();
-                    return -EFAULT;
-                }
-            }
             if ( rc == __HYPERVISOR_memory_op )
-                hypercall_xlat_continuation(NULL, 0x2, nat, arg);
+                hypercall_cancel_continuation();
+            return -EFAULT;
         }
 
+        if ( rc == __HYPERVISOR_memory_op )
+            hypercall_xlat_continuation(NULL, 0x2, nat, arg);
+
         break;
     }